#!/bin/sh
test "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" && {
  echo 'afl-system-config by Marc Heuse <mh@mh-sec.de>'
  echo
  echo $0
  echo
  echo afl-system-config has no command line options
  echo
  echo afl-system-config reconfigures the system to a high performance fuzzing state.
  echo "WARNING: this reduces the security of the system!"
  echo
  echo Note that there is also afl-persistent-config which sets additional permanent
  echo configuration options.
  exit 0
}
if [ $# -ne 0 ]; then
  echo "ERROR: Unknown option(s): $@"
  exit 1
fi

DONE=
PLATFORM=`uname -s`
echo This reconfigures the system to have a better fuzzing performance.
echo "WARNING: this reduces the security of the system!"
echo
if [ '!' "$EUID" = 0 ] && [ '!' `id -u` = 0 ] ; then
	echo "Warning: you need to be root to run this!"
	sleep 1
	# we do not exit as other mechanisms exist that allows to do this than
	# being root. let the errors speak for themselves.
fi
sleep 1
if [ "$PLATFORM" = "Linux" ] ; then
{
  sysctl -w kernel.core_uses_pid=0
  # Arch Linux requires core_pattern to be empty :(
  test -e /etc/arch-release && sysctl -w kernel.core_pattern=
  test -e /etc/arch-release || sysctl -w kernel.core_pattern=core
  sysctl -w kernel.randomize_va_space=0
  sysctl -w kernel.sched_child_runs_first=1
  sysctl -w kernel.sched_autogroup_enabled=1
  sysctl -w kernel.sched_migration_cost_ns=50000000 2>/dev/null
  sysctl -w kernel.sched_latency_ns=250000000 2>/dev/null
  sysctl -w vm.swappiness=10 2>/dev/null
  echo never > /sys/kernel/mm/transparent_hugepage/enabled
  test -e /sys/devices/system/cpu/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/scaling_governor
  test -e /sys/devices/system/cpu/cpufreq/policy0/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/policy*/scaling_governor
  test -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
  test -e /sys/devices/system/cpu/intel_pstate/no_turbo && echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
  test -e /sys/devices/system/cpu/cpufreq/boost && echo 1 > /sys/devices/system/cpu/cpufreq/boost
  test -e /sys/devices/system/cpu/intel_pstate/max_perf_pct && echo 100 > /sys/devices/system/cpu/intel_pstate/max_perf_pct
  test -n "$(which auditctl)" && auditctl -a never,task >/dev/null 2>&1
} > /dev/null
  echo Settings applied.
  echo
  dmesg | grep -E -q 'noibrs pcid nopti' || {
    echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
    echo '  /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off nokaslr no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"'
    echo
  }
  echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed.
  echo
  DONE=1
fi
if [ "$PLATFORM" = "FreeBSD" ] ; then
{
  sysctl kern.elf32.aslr.enable=0
  sysctl kern.elf64.aslr.enable=0
} > /dev/null
  echo Settings applied.
  echo
  cat <<EOF
In order to suppress core file generation during fuzzing it is recommended to set
me:\\
	:coredumpsize=0:
in the ~/.login_conf file for the user used for fuzzing.
EOF
  echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
  echo '  sysctl hw.ibrs_disable=1'
  echo 'Setting kern.pmap.pg_ps_enabled=0 into /boot/loader.conf might be helpful too.'
  echo
  DONE=1
fi
if [ "$PLATFORM" = "OpenBSD" ] ; then
  doas sysctl vm.malloc_conf=
  echo 'Freecheck on allocation in particular can be detrimental to performance.'
  echo 'Also we might not want necessarily to abort at any allocation failure.'
  echo 'System security features cannot be disabled on OpenBSD.'
  echo
  DONE=1
fi
if [ "$PLATFORM" = "DragonFly" ] ; then
  #/sbin/sysctl kern.corefile=/dev/null
  #echo Settings applied.
  cat <<EOF
In order to suppress core file generation during fuzzing it is recommended to set
me:\\
	:coredumpsize=0:
in the ~/.login_conf file for the user used for fuzzing.
EOF
  echo
  DONE=1
fi
if [ "$PLATFORM" = "NetBSD" ] ; then
{
  /sbin/sysctl -w security.models.extensions.user_set_cpu_affinity=1
} > /dev/null
  echo Settings applied.
  echo
  DONE=1
fi
if [ "$PLATFORM" = "Darwin" ] ; then
  sysctl kern.sysv.shmmax=524288000
  sysctl kern.sysv.shmmin=1
  sysctl kern.sysv.shmseg=48
  sysctl kern.sysv.shmall=131072000
  echo Settings applied.
  echo
  if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash\>') ; then
    echo
    echo Unloading the default crash reporter
    SL=/System/Library; PL=com.apple.ReportCrash
    sudo -u "$SUDO_USER" launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
    launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
    echo
  fi
  echo It is recommended to disable System Integrity Protection for increased performance.
  echo See: https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection
  echo
  DONE=1
fi
if [ "$PLATFORM" = "Haiku" ] ; then
  DEBUG_SERVER_DIR=~/config/settings/system/debug_server
  [ ! -d ${DEBUG_SERVER_DIR} ] && mkdir -p ${DEBUG_SERVER_DIR}
  SETTINGS=${DEBUG_SERVER_DIR}/settings
  [ -r ${SETTINGS} ] && grep -qE "default_action\s+kill" ${SETTINGS} && { echo "Nothing to do"; } || { \
    echo We change the debug_server default_action from user to silently kill; \
    [ ! -r ${SETTINGS} ] && echo "default_action kill" >${SETTINGS} || { mv ${SETTINGS} s.tmp; sed -e "s/default_action\s\s*user/default_action kill/" s.tmp > ${SETTINGS}; rm s.tmp; }; \
    echo Settings applied.; echo; \
  }
  DONE=1
fi
test -z "$DONE" && echo Error: Unknown platform: $PLATFORM
exit 0
